package fr.toto.triseries;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JOptionPane;

import static java.nio.file.StandardCopyOption.*;

import com.kokotchy.betaSeriesAPI.model.Episode;
import com.kokotchy.betaSeriesAPI.model.Season;
import com.kokotchy.betaSeriesAPI.model.Show;
import com.kokotchy.betaSeriesAPI.model.SubtitleLanguage;

import fr.toto.constantes.Constantes;
import fr.toto.exceptions.ProcessException;
import fr.toto.files.AccesFile;
import fr.toto.subtitles.Soutitre;

public class Video implements Runnable, Constantes {

	private static Pattern pat = Pattern.compile(Regex.SERIE + Regex.VIDEOFILE);
	private String serie;
	private int season;
	private int episode;
	private String reste;
	private String extention;
	private String url;
	private Path file;
	private Path filename;
	private Episode ep = null;
	private static SubtitleLanguage languageSub = settings.getSubLang();
	private Show show = null;
	private Show serieStatus = null;
	public static boolean DEBUG = true;

	public Video(Path file) {
		this.file = file;
		this.filename = file.getFileName();

	}

	@Override
	public void run() {
		if (!analyseFile())
			return;
		// La méthode scraper ne me convient pas pour l'instant
		// ep = BetaSeriesQuery.scrapeFile(filename);
		if (ep != null) {
			EpisodesSet.add(ep);
			if (!ep.isDownloaded()) {
				ep.setDownloaded(true);
				BetaSeriesQuery.setDownloaded(ep);
			}
		} else {
			if (findUrl().isEmpty())
				return;
			if (!getEpisode()) {
				urlnotfound();
				return;
			}
		}
		if (DEBUG)
			System.out.println(ep.toString());
		moveEpisode();
		if (languageSub != null && !languageSub.equals(SubtitleLanguage.UNKNOWN)) {
			if (languageSub.equals(SubtitleLanguage.VOVF)) {
				new Soutitre(ep, SubtitleLanguage.VO, reste).getSubtitle(ep);
				new Soutitre(ep, SubtitleLanguage.VF, reste).getSubtitle(ep);
			} else
				new Soutitre(ep, languageSub, reste).getSubtitle(ep);
		}
		return;
	}

	private void moveEpisode() {

		Path filedest = Paths.get(Regex.getEpisodeDest(ep).toString() + "."
				+ extention);

		try {
			Files.createDirectories(filedest.getParent());
			Files.move(file, filedest, REPLACE_EXISTING);
		} catch (Exception e) {
			new ProcessException(e);
		}

	}

	private void addShow() {
		BetaSeriesQuery.addSerie(url);
		if (show != null) {
			SeriesSet.add(show);
		}
		Set<Season> sai = BetaSeriesQuery.getShowsEpisode(url);
		for (Season s1 : sai) {
			for (Episode epi : s1.getEpisodes().values()) {
				EpisodesSet.add(epi);
			}
		}
	}

	private boolean getEpisode() {

		ep = EpisodesSet.find(url, season, episode);
		if (ep == null) {
			ep = BetaSeriesQuery.getEpisode(url, season, episode);
			if (ep == null)
				return false;
			EpisodesSet.add(ep);
		}
		if (!ep.isDownloaded()) {
			ep.setDownloaded(true);
			BetaSeriesQuery.setDownloaded(ep);
		}
		return true;
	}

	public boolean analyseFile() {

		Matcher m = pat.matcher(filename.toString());
		if (!m.matches())
			return false;
		serie = m.group(1).replace(".", " ").replace("_", " ").trim();
		season = Integer.parseInt(m.group(2));
		episode = Integer.parseInt(m.group(3));
		reste = m.group(4);
		extention = m.group(5);
		return true;

	}

	private String findUrl() {

		// Recherche dans fichier Series
		url = seriesFile.getProperty(serie.toLowerCase(), "null");

		// SI pas trouvé :
		if (url.equals("null")) {

			url = SeriesSet.searchUrl(serie);
			if (url.isEmpty()) {
				// - Recherche sur site
				Set<Show> shows = BetaSeriesQuery.search(serie.replaceAll(
						Regex.SHOWNAME, " ").trim());
				show = Regex.getBestUrl(shows, serie, 0);
				if (show != null)
					url = show.getUrl();
			}

			if (url.isEmpty()) {
				urlnotfound();
			} else {
				serieStatus = SeriesSet.findShow(url);
				if (serieStatus == null)
					addShow();
				// - ajout dans fichier (avec url vide si pas trouvé)
				seriesFile.setProperty(serie.toLowerCase(), url);
				try {
					seriesFile.store(new OutputStreamWriter(
							new FileOutputStream(LISTSHOWPATH.toString()),
							CharsetName), MESSAGES
							.getString("serieFileExplanation"));
				} catch (Exception e) {
					new ProcessException(e);
				}
			}

		}
		return url;
	}

	private void urlnotfound() {
		try {
			// préparation du fichier pour ajouter l'url manuellement
			seriesFile.setProperty(serie.toLowerCase(), "");

			seriesFile.store(new OutputStreamWriter(new FileOutputStream(
					LISTSHOWPATH.toString()), CharsetName), MESSAGES
					.getString("serieFileExplanation"));

			int set = JOptionPane.showConfirmDialog(
					null,
					String.format(MESSAGES.getString("shownotfoundMsg"),
							file.getFileName()), PGMNAME,
					JOptionPane.YES_NO_OPTION);
			if (set == JOptionPane.YES_OPTION) {
				AccesFile.Open(LISTSHOWPATH);
			}

		} catch (Exception e) {
			new ProcessException(e);
		}

	}

}
